import { useState, useEffect } from 'react' 
import style from './index.module.scss'
import { GetRoleFnc, DeleteRoleChildFnc } from '@/api/roles'
import { ShowRightFnc, SetRightFnc } from '@/api/roles'
import { itemType } from './type'
import { Breadcrumb, Table, Button, Row, Col, Tag, message, Modal, Tree } from 'antd'
import { EditOutlined, DeleteOutlined, UnorderedListOutlined, CaretRightOutlined } from '@ant-design/icons'
import EditRoles from './components/Edit'

const Roles = () => {
  const [dataSource, setDataSource] = useState([])  // table数据源  
  const [isModalOpen, setIsModalOpen] = useState(false) // 添加修改用户的盒子  
  const [id, setID] = useState('') // roleID 编辑盒子使用
  const [rowID, setRowID] = useState('') // roleID 展开行使用
  const [roleName, setRoleName] = useState('') // roleName
  const [roleDesc, setRoleDesc] = useState('') // roleDesc
  const [treeData, setTreeData] = useState([]) // 树形数据  
  const [defkeys, setDefkeys] = useState<any>([]) // 选中的节点ID数值
  const [isGiveRoleOpen, setIsGiveRoleOpen] = useState(false) // 分配角色盒子  

  const columns = [
    {title: '角色ID', dataIndex: 'id', key: 'id', width: 100},
    {title: '角色名称', dataIndex: 'roleName', key: 'roleName', width: 170, ellipsis: true},
    {title: '角色描述', dataIndex: 'roleDesc', key: 'roleDesc', width: 130, ellipsis: true},
    {title: '操作', width: 250, render: (_:any, record: {id: string, roleName: string, roleDesc: string, sub: []}) => {
      return (
        <>
          <Button type='primary' size='small' icon={<EditOutlined/>} onClick={() => changeDialog(true, record.id, record.roleName, record.roleDesc)}>编辑</Button> 
          <Button type="primary" danger size='small' icon={<DeleteOutlined/>} style={{margin: '0 6px 0'}}>删除</Button> 
          <Button color="yellow" variant="solid" size='small' icon={<UnorderedListOutlined/>} onClick={() => giveRoleOpen(record)}>设置</Button>
        </>
      )
    }}
  ]

  // 数据初始化
  const init = async () => {
   const res = await GetRoleFnc()
   const res2 = await ShowRightFnc() // 分配角色
   if(res.data.meta.status === 200) {
    setTreeData(res2.data.data)
    let arr = []
    arr = res.data.data.map((item: itemType) => {
      return {
        key: item.id,
        id: item.id,
        roleName: item.roleName,
        roleDesc: item.roleDesc,
        sub: item.children // 这里的sub 不能取名叫children
      }
    })
    setDataSource(arr)
   }
  }
  useEffect(() => { init() }, [])

  // 修改盒子 给子组件使用
  const changeDialog = (flag: boolean, id = '', roleName = '', roleDesc = '') => {
    setIsModalOpen(flag)
    setID(id)
    setRoleName(roleName)
    setRoleDesc(roleDesc)
  }

  // 展开行获得数据
  const subTabLine = (record: {sub: []}) => {
    return record.sub.map((item: {children: [], id: number, authName: string}) => {
      if(item.children.length !== 0) {
        return (
          <Row key={item.id} className={style.row}>
            <Col span={6} className={style.centerCol}>
              <Tag color='blue' closable onClose={() => deleteTag(item.id)}>{item.authName}</Tag>
              <CaretRightOutlined/>
            </Col>

            <Col span={18}>
              {item.children.map((itemB: {children: [], id: number, authName: string}) => {
                return (
                  <Row key={itemB.id}>
                    <Col span={6}>
                      <Tag color='green' closable onClose={() => deleteTag(itemB.id)}>{itemB.authName}</Tag>
                      <CaretRightOutlined/>
                    </Col>
                    <Col span={18}>
                      {itemB.children.map((itemC: {id: number, authName: string}) => {
                        return (
                          <Tag className={style.lastTag} key={itemC.id} color='volcano' closable onClose={() => deleteTag(itemC.id)}>{itemC.authName}</Tag>
                        )
                      })}
                    </Col>
                  </Row> 
                )
              })}
            </Col>
          </Row>
        )
      } 
    })    
  }
  
  // 删除tag
  const deleteTag = async (tagID: number) => {
    const res = await DeleteRoleChildFnc(parseInt(rowID), tagID)
    if(res.data.meta.status === 200) {
      message.success('更新成功', 1.5, () => {
        init()
      })
    }
  }

  const getLeafKeys = (node: {children: [], id: number}, arr: number[]) => { // 通过递归的形式获取角色下所有三级权限的ID并保存到数组中
    if (!node.children) {
       if(arr.includes(node.id)){
         return false
       } else {
          return arr.push(node.id) // 将number转为字符串
       }
    }
    node.children.forEach((item: {children: [], id: number}) => {
        getLeafKeys(item, arr)
    })
  }

  // 打开分配角色盒子
  const giveRoleOpen = async (record: {id: string, roleName: string, roleDesc: string, sub: []}) => {
    setIsGiveRoleOpen(true) 
    setRowID(record.id)
    let obj: any = { // 因为getLeafKeys需要遍历children，而item对象里面是subs，所以要把subs属性名改为children
      id: record.id,
      roleName: record.roleName,
      roleDesc: record.roleDesc,
      children: record.sub,
    }
    getLeafKeys(obj, defkeys)
  }

  // 分配角色
  const roleOK = async () => {
    let keys = defkeys
    let rids = keys.join(',')
    const res = await SetRightFnc(parseInt(rowID), {rids: rids})
    if(res.data.meta.status === 200) {
      message.success('更新成功', 1.5, () => {
        setIsGiveRoleOpen(false) 
        init()
      })
    }
  }

  return (
   <>
    <Breadcrumb items={[{ title: '权限管理' }, { title: '角色列表' }]} />

    {/* table数据 */}
    <div className={style.rolesContent}>
      <Table dataSource={dataSource} columns={columns} bordered={true} scroll={{x:500}} expandable={{
        expandedRowRender: (record: any) => subTabLine(record),
        onExpand: (_,event) => setRowID(event.id)
      }}/>  
    </div>

    {/* 编辑角色盒子 */}
    <EditRoles isModalOpen={isModalOpen} changeDialog={changeDialog} id={id} roleName={roleName} roleDesc={roleDesc} init={init}/>

    {/* 分配角色盒子 */}
    <Modal title='分配权限' open={isGiveRoleOpen} okText='确定' cancelText='取消' onOk={() => roleOK()} onCancel={() => setIsGiveRoleOpen(false)}>
       <Tree treeData={treeData} checkable defaultCheckedKeys={defkeys} fieldNames={{title: 'authName', key: 'id', children: 'children'}}
       onCheck={(checkedKeys: any, e: any) => setDefkeys([...checkedKeys, ...e.halfCheckedKeys])}/>
    </Modal>
   </>
  )
}

export default Roles 